home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / util / directjpeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-25  |  5.3 KB  |  223 lines

  1. /* directjpeg.c- loads a jpeg file directly into a XImage
  2.  *
  3.  *  WindowMaker window manager
  4.  * 
  5.  *  Copyright (c) 1999 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23.  
  24. #include "../src/config.h"
  25.  
  26.  
  27.  
  28. #ifdef USE_JPEG
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33.  
  34. #include <jpeglib.h>
  35.  
  36. #include "../wrlib/wraster.h"
  37.  
  38. #include <setjmp.h>
  39.  
  40.  
  41. struct my_error_mgr {
  42.   struct jpeg_error_mgr pub;    /* "public" fields */
  43.  
  44.   jmp_buf setjmp_buffer;    /* for return to caller */
  45. };
  46.  
  47. typedef struct my_error_mgr * my_error_ptr;
  48.  
  49. /*
  50.  * Here's the routine that will replace the standard error_exit method:
  51.  */
  52.  
  53. static void
  54. my_error_exit (j_common_ptr cinfo)
  55. {
  56.   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  57.   my_error_ptr myerr = (my_error_ptr) cinfo->err;
  58.  
  59.   /* Always display the message. */
  60.   /* We could postpone this until after returning, if we chose. */
  61.   (*cinfo->err->output_message) (cinfo);
  62.  
  63.   /* Return control to the setjmp point */
  64.   longjmp(myerr->setjmp_buffer, 1);
  65. }
  66.  
  67.  
  68. static Bool
  69. canLoad(RContext *rc)
  70. {
  71.     if (rc->depth != 16 || rc->vclass != TrueColor
  72.     || rc->red_offset!=11 || rc->green_offset!=5 || rc->blue_offset!=0)
  73.     return False;
  74.  
  75.     return True;
  76. }
  77.  
  78.  
  79. static void
  80. readData(RContext *rc, struct jpeg_decompress_struct *cinfo,
  81.      JSAMPROW *buffer, RXImage *ximg) 
  82. {
  83.     int i, j;
  84.     unsigned long pixel;
  85.     int y = 0;
  86.  
  87.     /* for 16bpp only */
  88.     while (cinfo->output_scanline < cinfo->output_height) {
  89.  
  90.         jpeg_read_scanlines(cinfo, buffer, (JDIMENSION)1);
  91.  
  92.     if (cinfo->out_color_space==JCS_RGB) {
  93.         for (i=0,j=0; i<cinfo->image_width; i++) {
  94.  
  95.         printf("%i %i %i\n",
  96.                (((unsigned long)buffer[0][j])&0xf8)<<8,
  97.                (((unsigned long)buffer[0][j+1])&0xf4)<<3,
  98.                (((unsigned long)buffer[0][j+2]))>>3);
  99.         
  100.         pixel = (((unsigned long)buffer[0][j++])&0xf8)<<8
  101.             |(((unsigned long)buffer[0][j++])&0xf4)<<3
  102.             |(((unsigned long)buffer[0][j++]))>>3;
  103.  
  104.         XPutPixel(ximg->image, i, y, pixel);
  105.         }
  106.     } else {
  107.         for (i=0,j=0; i<cinfo->image_width; i++, j++) {
  108.  
  109.         pixel = (unsigned long)buffer[0][j]<<8
  110.             |(unsigned long)buffer[0][j]<<3
  111.             |(unsigned long)buffer[0][j]>>3;
  112.  
  113.         XPutPixel(ximg->image, i, y, pixel);
  114.         }
  115.     }
  116.     y++;
  117.     }
  118. }
  119.  
  120.  
  121.  
  122. Pixmap
  123. LoadJPEG(RContext *rc, char *file_name, int *width, int *height)
  124. {
  125.     struct jpeg_decompress_struct cinfo;
  126.     JSAMPROW buffer[1];
  127.     FILE *file;
  128.     struct my_error_mgr jerr;
  129.     RXImage *ximg = NULL;
  130.     unsigned char buf[8];
  131.     Pixmap p = None;
  132.  
  133.     if (!canLoad(rc))
  134.     return None;
  135.  
  136.     file = fopen(file_name, "r");
  137.     if (!file) {
  138.     return None;
  139.     }
  140.     if (fread(buf, 2, 1, file) != 1) {
  141.     fclose(file);
  142.     return None;
  143.     }
  144.     if (buf[0] != 0xff || buf[1] != 0xd8) {
  145.     fclose(file);
  146.     return None;
  147.     }
  148.     rewind(file);
  149.  
  150.     cinfo.err = jpeg_std_error(&jerr.pub);
  151.     jerr.pub.error_exit = my_error_exit;
  152.     /* Establish the setjmp return context for my_error_exit to use. */
  153.     if (setjmp(jerr.setjmp_buffer)) {
  154.        /* If we get here, the JPEG code has signaled an error.
  155.     * We need to clean up the JPEG object, close the input file, and return.
  156.     */
  157.     jpeg_destroy_decompress(&cinfo);
  158.     fclose(file);
  159.  
  160.     if (ximg) {
  161.         RDestroyXImage(rc, ximg);
  162.     }
  163.     
  164.     return None;
  165.     }
  166.  
  167.     jpeg_create_decompress(&cinfo);
  168.  
  169.     jpeg_stdio_src(&cinfo, file);
  170.   
  171.     jpeg_read_header(&cinfo, TRUE);
  172.  
  173.     buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
  174.     if (!buffer[0]) {
  175.     RErrorCode = RERR_NOMEMORY;
  176.     goto bye;
  177.     }
  178.  
  179.     if(cinfo.jpeg_color_space==JCS_GRAYSCALE) {
  180.        cinfo.out_color_space=JCS_GRAYSCALE;
  181.     } else
  182.         cinfo.out_color_space = JCS_RGB;
  183.     cinfo.quantize_colors = FALSE;
  184.     cinfo.do_fancy_upsampling = FALSE;
  185.     cinfo.do_block_smoothing = FALSE;
  186.     jpeg_calc_output_dimensions(&cinfo);
  187.  
  188.     ximg = RCreateXImage(rc, rc->depth, cinfo.image_width, cinfo.image_height);
  189.     if (!ximg) {
  190.        goto bye;
  191.     }
  192.     jpeg_start_decompress(&cinfo);
  193.  
  194.     readData(rc, &cinfo, buffer, ximg);
  195.  
  196.     jpeg_finish_decompress(&cinfo);
  197.  
  198.     p = XCreatePixmap(rc->dpy, rc->drawable, cinfo.image_width, 
  199.               cinfo.image_height, rc->depth);
  200.  
  201.     RPutXImage(rc, p, rc->copy_gc, ximg, 0, 0, 0, 0, cinfo.image_width,
  202.            cinfo.image_height);
  203.  
  204.     *width = cinfo.image_width;
  205.     *height = cinfo.image_height;
  206.     
  207.   bye:
  208.     jpeg_destroy_decompress(&cinfo);
  209.  
  210.     fclose(file);
  211.  
  212.     if (buffer[0])
  213.     free(buffer[0]);  
  214.  
  215.     if (ximg)
  216.     RDestroyXImage(rc, ximg);
  217.     
  218.     return p;
  219. }
  220.  
  221. #endif /* USE_JPEG */
  222.  
  223.